package dev.hxliu.cn.util;

import dev.hxliu.cn.methodHandles.InjectValueHandle;
import dev.hxliu.cn.javassist.AdapterFactory;
import dev.hxliu.cn.javassist.InjectAdapter;
import org.jetbrains.annotations.Contract;


@SuppressWarnings("unused")
public class InjectValueUtil {

    // -Djava.system.class.loader=org.lintong.ai.inject.CustomClassLoader
//    private
    @Contract("_->param1")
    public static <T> T injectObject(T object) {
        if (object == null) {
            return null;
        }
        InjectValueHandle[] list =  InjectValueHandle.getInjectValueHandleList(object.getClass());

        try {
            /*
             * 防止对应方法出现重复的网络请求，这里对结果值进行本地缓存
             */
//            Map<Class<? extends InjectMethod<?>> ,Object> enumObjectHashMap = new HashMap<>(32);
//            for (int i = 0; i < list.length; i++) {
//                InjectValueHandle item = list[0];
//            }
            for (InjectValueHandle item : list) {
                boolean isCover = item.isCover();
                if(isCover || item.read().invoke(object) ==null){
//                    try {
                        switch (item.enumType()){
                            case InjectMethodArgObject->item.write().invoke(object,item.bound().invoke(object));
                            case InjectMethodArgColumn->item.write().invoke(object,item.bound().invoke(item.read().invoke(object)));
                            case InjectMethod->item.write().invoke(object,item.bound().invoke());
                            case NONE->{}
                        }
//                    } catch (Throwable e) {
//                        log.error("获取injectValue失败,e->{}", e.getMessage(),e);
//                        throw new RuntimeException(e);
//                    }
//                    finally {
//                        enumObjectHashMap.clear();
//                    }
                }
            }
        } catch (Throwable e) {
            throw new RuntimeException(e);
        }
//        finally {
//            enumObjectHashMap.clear();
//        }

        return object;
    }
    @Contract("_,_->param1")
    public static <T> T injectObject(T object,Class<T> clazz) {
        if (object == null) {
            return null;
        }
        InjectValueHandle[] list =  InjectValueHandle.getInjectValueHandleList(clazz);

        try {
            /*
             * 防止对应方法出现重复的网络请求，这里对结果值进行本地缓存
             */
//            Map<Class<? extends InjectMethod<?>> ,Object> enumObjectHashMap = new HashMap<>(32);
//            for (int i = 0; i < list.length; i++) {
//                InjectValueHandle item = list[0];
//            }
            for (InjectValueHandle item : list) {
                boolean isCover = item.isCover();
                if(isCover || item.read().invoke(object) ==null){
//                    try {
                    switch (item.enumType()){
                        case InjectMethodArgObject->item.write().invoke(object,item.bound().invoke(object));
                        case InjectMethodArgColumn->item.write().invoke(object,item.bound().invoke(item.read().invoke(object)));
                        case InjectMethod->item.write().invoke(object,item.bound().invoke());
                        case NONE->{}
                    }
//                    } catch (Throwable e) {
//                        log.error("获取injectValue失败,e->{}", e.getMessage(),e);
//                        throw new RuntimeException(e);
//                    }
//                    finally {
//                        enumObjectHashMap.clear();
//                    }
                }
            }
        } catch (Throwable e) {
            throw new RuntimeException(e);
        }
//        finally {
//            enumObjectHashMap.clear();
//        }

        return object;
    }
    @Contract("_,_->param1")
    public static <T> T injectObject1(T object,Class<T> clazz)  {

        if (object == null) {
            return null;
        }
        InjectAdapter<T> injectAdapter = AdapterFactory.createAdapter(clazz);
        injectAdapter.inject(object);
        return object;
    }


    @Contract("_->param1")
    public static <T> T injectObject1(T object)  {
        if (object == null) {
            return null;
        }
        InjectAdapter<T> injectAdapter = AdapterFactory.createAdapter((Class<T>) object.getClass());
        injectAdapter.inject(object);
        return object;
    }

}
